//
// Created by Administrator on 2023/11/18.
//

#include "iostream"
#include "cstring"

using namespace std;
const int INF = 0x3f3f3f3f, N = 210;

int g[N][N];
int n, m, k;

void floyd() {
    //第一个循环代表经过k点松弛
    //每迭代一次。从i到j就多考虑了一个结点
    for (int k = 1; k <= n; ++k) {
        //以下两重循环表示图中所有点都经过k点松弛
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
            }
        }
    }
}

int main() {
    cin >> n >> m >> k;


    //是不是一定对角线为0？
    //理论上应该是0（因为在数学上，一个节点到它自身的距离是0）
    //实际操作中好像并不会影响
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            if(i==j) g[i][j]=0;
            else g[i][j]=INF;
        }
    }

    while (m--) {
        int x, y, z;
        cin >> x >> y >> z;
        g[x][y] = z;
    }
    floyd();

    while (k--) {
        int x, y;
        cin >> x >> y;

        //有负边存在。就得用>
        if(g[x][y]>INF/2) cout<<"impossible"<<endl;
        else cout<<g[x][y]<<endl;
    }
}